package com.ruoyi.system.service.impl;

import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.service.IOssStrategy;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.mapper.SysOssMapper;
import com.ruoyi.system.service.ISysOssService;
import com.sun.org.apache.regexp.internal.RE;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * @author 最爱喝兽奶
 * @create 2022/6/13
 **/
@SuppressWarnings("ALL")
@Service
public class SysOssServiceImpl implements ISysOssService {

    private final Logger logger = LoggerFactory.getLogger(SysOssServiceImpl.class);

    @Autowired
    private SysOssMapper sysOssMapper;

    @Override
    public List<SysOss> queryListByIds(List<String> ids) {
        List<String> queryIds = new ArrayList<>();
        for (int i = 0; i < ids.size(); i++) {
            String id = ids.get(i);
            // 如果前端传入的id是空直接筛选掉
            if (null != id) {
                queryIds.add(id);
            }
        }
        return sysOssMapper.queryByOssIds(queryIds);
    }

    @Override
    public SysOss queryById(String id) {
        if (null == id) {
            logger.error("不能传入空的id");
            return null;
        }else {
            return sysOssMapper.queryByOssId(id);
        }
    }

    @Override
    public SysOss upload(MultipartFile file) {
        if (null != file) {
            // 获取源文件的名称
            String originalFileName = file.getOriginalFilename();
            assert originalFileName != null;
            // 获取文件的后缀名
            String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length());
            // 获取文件存储策略
            IOssStrategy strategy = OssFactory.instance();
            UploadResult uploadResult = null;
            try {
                // 将文件上传至文件服务器
                uploadResult = strategy.uploadSuffix(file.getInputStream(), suffix, file.getContentType());
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            }
            // 保存文件信息
            SysOss sysOss = new SysOss();
            // 设置url全路径
            sysOss.setUrl(uploadResult.getUrl());
            // 设置文件后缀名
            sysOss.setFileSuffix(suffix);
            // 设置文件名
            sysOss.setFileName(uploadResult.getFilename());
            // 设置文件原名
            sysOss.setOriginalName(originalFileName);
            // 设置创建时间
            sysOss.setCreateTime(new Date());
            // 设置更新时间
            sysOss.setUpdateTime(new Date());
            sysOss.setCreateBy("admin");
            sysOss.setUpdateBy("admin");
            sysOss.setFileSize(String.valueOf(file.getSize()));
            // TODO: 先写死吧
            sysOss.setService("minio");
//            sysOss.setCreateBy(SecurityUtils.getUsername());
//            sysOss.setCreateBy(SecurityUtils.getUsername());
            sysOssMapper.insert(sysOss);
            return sysOss;
        }
        logger.error("传入文件不能为空");
        return null;
    }

    @Override
    public SysOss upload(InputStream is, String fileName, String suffix) {
        if (null != is) {
            IOssStrategy strategy = OssFactory.instance();
            UploadResult uploadResult = null;
            // 将文件上传至文件服务器
            uploadResult = strategy.uploadSuffix(is, suffix, null);
            // 保存文件信息
            SysOss sysOss = new SysOss();
            // 设置url全路径
            sysOss.setUrl(uploadResult.getUrl());
            // 设置文件后缀名
            sysOss.setFileSuffix(suffix);
            // 设置文件名
            sysOss.setFileName(uploadResult.getFilename());
            // 设置文件原名
            sysOss.setOriginalName(fileName);
            // 设置创建时间
            sysOss.setCreateTime(new Date());
            // 设置更新时间
            sysOss.setUpdateTime(new Date());
            sysOss.setCreateBy("admin");
            sysOss.setUpdateBy("admin");
            // TODO: 先写死吧
            sysOss.setService("minio");
            sysOssMapper.insert(sysOss);
            return sysOss;
        }
        logger.error("传入文件不能为空");
        return null;
    }

    @Override
    public SysOss upload(byte[] flush, String fileName, String suffix) {
        if (null != flush) {
            IOssStrategy strategy = OssFactory.instance();
            UploadResult uploadResult = null;
            // 将文件上传至文件服务器
            uploadResult = strategy.uploadSuffix(flush, suffix, null);
            // 保存文件信息
            SysOss sysOss = new SysOss();
            // 设置url全路径
            sysOss.setUrl(uploadResult.getUrl());
            // 设置文件后缀名
            sysOss.setFileSuffix(suffix);
            // 设置文件名
            sysOss.setFileName(uploadResult.getFilename());
            // 设置文件原名
            sysOss.setOriginalName(fileName);
            // 设置创建时间
            sysOss.setCreateTime(new Date());
            // 设置更新时间
            sysOss.setUpdateTime(new Date());
            sysOss.setCreateBy("admin");
            sysOss.setUpdateBy("admin");
            // TODO: 先写死吧
            sysOss.setService("minio");
            sysOssMapper.insert(sysOss);
            return sysOss;
        }
        logger.error("传入文件不能为空");
        return null;
    }

    @Override
    public byte[] download(String ossId) {
        SysOss sysOss = sysOssMapper.selectById(ossId);
        if (null != sysOss) {
            try {
                URL url = new URL(sysOss.getUrl());
                InputStream inputStream = url.openConnection().getInputStream();
                ByteArrayOutputStream baso = new ByteArrayOutputStream();
                int len = -1;
                byte[] flush = new byte[1024];
                while ((len = inputStream.read(flush)) != -1) {
                    baso.write(flush,  0, len);
                }
                return baso.toByteArray();
            } catch (Exception e) {
                logger.error("图片url连接异常");
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            // TODO: 做一些业务上的校验，还没想好写什么。。。。
        }
        List<SysOss> list = sysOssMapper.queryByOssIds(ids);
        IOssStrategy strategy = OssFactory.instance();
        try {
            for (int i = 0; i < list.size(); i++) {
                SysOss sysOss = list.get(i);
                // 删除文件服务器里的文件
                strategy.delete(sysOss.getUrl());
                // 删除文件列表中的文件
                sysOssMapper.deleteById(sysOss.getOssId());
            }
            return true;
        } catch (Exception e) {
            logger.error("文件删除失败", e.getMessage());
        }
        // 删除文件存储表里的文件
        return false;
    }

    @Override
    public InputStream getInputStreamByOssId(Serializable ossId) {
        SysOss sysOss = sysOssMapper.selectById(ossId);
        try {
            URL url = new URL(sysOss.getUrl());
            return url.openConnection().getInputStream();
        } catch (MalformedURLException e) {
            logger.error("网络读取文件失败");
            throw new RuntimeException("读取文件失败，请重新上传文件。");
        } catch (IOException e) {
            logger.error("打开输入流失败");
            throw new RuntimeException("打开输入流失败");
        }
    }
}
